package com.example.cachedemo;

import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingDeque;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

public final class ThreadUtil {
    // cpu核心数
    private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();
    // 线程池核心线程数
    private static final int CORE_POOL_SIZE = CPU_COUNT + 1;
    // 线程池核心线程数
    private static final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2 + 1;
    // 线程超时时长
    private static final long KEEP_ALIVE = 10;
    // 线程工厂
    private static final ThreadFactory threadFactory = new ThreadFactory() {
        private final AtomicInteger count = new AtomicInteger(1);

        @Override
        public Thread newThread(Runnable r) {
            return new Thread(r, "ThreadUtil#" + count.getAndIncrement());
        }
    };
    // 线程池
    private static final Executor customerExecutor = new ThreadPoolExecutor(
            CORE_POOL_SIZE, MAXIMUM_POOL_SIZE, KEEP_ALIVE, TimeUnit.SECONDS,
            new LinkedBlockingDeque<Runnable>(), threadFactory);

    /**
     * 自定义线程池 运行
     * @param runnable runnable
     */
    public static void customer(Runnable runnable) {
        customerExecutor.execute(runnable);
    }


    // 固定线程池的线程数量
    private static final int FIXED_THREAD_NUMBER = 5;
    private static final ExecutorService fixedExecutor = Executors.newFixedThreadPool(FIXED_THREAD_NUMBER);

    /**
     *  固定线程池 运行
     * @param runnable runnable
     */
    public static void fixed(Runnable runnable) {
        fixedExecutor.execute(runnable);
    }

    // 单线程池
    private static final ExecutorService singleExecutor = Executors.newSingleThreadExecutor();

    /**
     * 单线程池 运行
     * @param runnable runnable
     */
    public static void single(Runnable runnable) {
        singleExecutor.execute(runnable);
    }

    // 缓存线程池
    private static final ExecutorService cachedExecutor = Executors.newCachedThreadPool();

    /**
     * 缓存线程池 运行
     * @param runnable runnable
     */
    public static void cached(Runnable runnable) {
        cachedExecutor.execute(runnable);
    }

    // 定时线程池
    private static final ScheduledExecutorService scheduleExecutor = Executors.newScheduledThreadPool(CORE_POOL_SIZE);

    /**
     *  延时执行
     * @param runnable runnable
     * @param seconds  延时的秒数
     */
    public static void after(Runnable runnable, int seconds) {
        scheduleExecutor.schedule(runnable, seconds, TimeUnit.SECONDS);
    }

    /**
     * 延时并周期执行
     * @param runnable runnable
     * @param after    延时的秒数
     * @param cycle    周期间隔的秒数
     */
    public static void afterAndCycle(Runnable runnable, int after, int cycle) {
        scheduleExecutor.scheduleAtFixedRate(runnable, after, cycle, TimeUnit.SECONDS);
    }
}
